package com.joyxy.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 图像匹配工具类
 * 用于在屏幕截图中查找特定的图像模板
 */
public class ImageMatcher {
    private static final Logger logger = LoggerFactory.getLogger(ImageMatcher.class);
    
    private static final double DEFAULT_THRESHOLD = 0.8;
    
    public ImageMatcher() {
        logger.info("图像匹配工具初始化完成");
    }
    
    /**
     * 在源图像中查找模板图像
     */
    public Point findImage(BufferedImage source, String templatePath) {
        return findImage(source, templatePath, DEFAULT_THRESHOLD);
    }
    
    /**
     * 在源图像中查找模板图像（指定相似度阈值）
     */
    public Point findImage(BufferedImage source, String templatePath, double threshold) {
        try {
            File templateFile = new File(templatePath);
            if (!templateFile.exists()) {
                logger.warn("模板图像文件不存在: {}", templatePath);
                return null;
            }
            
            BufferedImage template = ImageIO.read(templateFile);
            return findImage(source, template, threshold);
            
        } catch (IOException e) {
            logger.error("读取模板图像失败: {}", templatePath, e);
            return null;
        }
    }
    
    /**
     * 在源图像中查找模板图像
     */
    public Point findImage(BufferedImage source, BufferedImage template, double threshold) {
        if (source == null || template == null) {
            return null;
        }
        
        int sourceWidth = source.getWidth();
        int sourceHeight = source.getHeight();
        int templateWidth = template.getWidth();
        int templateHeight = template.getHeight();
        
        if (templateWidth > sourceWidth || templateHeight > sourceHeight) {
            logger.warn("模板图像尺寸大于源图像");
            return null;
        }
        
        double bestMatch = -1;
        Point bestLocation = null;
        
        // 滑动窗口匹配
        for (int y = 0; y <= sourceHeight - templateHeight; y++) {
            for (int x = 0; x <= sourceWidth - templateWidth; x++) {
                double similarity = calculateSimilarity(source, template, x, y);
                
                if (similarity > bestMatch && similarity >= threshold) {
                    bestMatch = similarity;
                    bestLocation = new Point(x + templateWidth / 2, y + templateHeight / 2);
                }
            }
        }
        
        if (bestLocation != null) {
            logger.debug("找到匹配图像，相似度: {:.2f}, 位置: ({}, {})", 
                        bestMatch, bestLocation.x, bestLocation.y);
        } else {
            logger.debug("未找到匹配图像，最高相似度: {:.2f}", bestMatch);
        }
        
        return bestLocation;
    }
    
    /**
     * 计算两个图像区域的相似度
     */
    private double calculateSimilarity(BufferedImage source, BufferedImage template, int startX, int startY) {
        int templateWidth = template.getWidth();
        int templateHeight = template.getHeight();
        
        long totalDifference = 0;
        long totalPixels = templateWidth * templateHeight;
        
        for (int y = 0; y < templateHeight; y++) {
            for (int x = 0; x < templateWidth; x++) {
                int sourceRGB = source.getRGB(startX + x, startY + y);
                int templateRGB = template.getRGB(x, y);
                
                // 计算RGB差值
                int sourceR = (sourceRGB >> 16) & 0xFF;
                int sourceG = (sourceRGB >> 8) & 0xFF;
                int sourceB = sourceRGB & 0xFF;
                
                int templateR = (templateRGB >> 16) & 0xFF;
                int templateG = (templateRGB >> 8) & 0xFF;
                int templateB = templateRGB & 0xFF;
                
                int diffR = Math.abs(sourceR - templateR);
                int diffG = Math.abs(sourceG - templateG);
                int diffB = Math.abs(sourceB - templateB);
                
                totalDifference += diffR + diffG + diffB;
            }
        }
        
        // 计算相似度 (0-1, 1表示完全相同)
        double maxDifference = totalPixels * 3 * 255; // 每个像素最大差值
        return 1.0 - (double) totalDifference / maxDifference;
    }
    
    /**
     * 查找所有匹配的位置
     */
    public java.util.List<Point> findAllMatches(BufferedImage source, String templatePath, double threshold) {
        java.util.List<Point> matches = new java.util.ArrayList<>();
        
        try {
            BufferedImage template = ImageIO.read(new File(templatePath));
            
            int sourceWidth = source.getWidth();
            int sourceHeight = source.getHeight();
            int templateWidth = template.getWidth();
            int templateHeight = template.getHeight();
            
            for (int y = 0; y <= sourceHeight - templateHeight; y++) {
                for (int x = 0; x <= sourceWidth - templateWidth; x++) {
                    double similarity = calculateSimilarity(source, template, x, y);
                    
                    if (similarity >= threshold) {
                        matches.add(new Point(x + templateWidth / 2, y + templateHeight / 2));
                    }
                }
            }
            
        } catch (IOException e) {
            logger.error("查找所有匹配项失败", e);
        }
        
        return matches;
    }
} 